/*
 *  Copyright (C) 2010 Zubanov Dmitry
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


/**
 *
 * @author Zubanov Dmitry aka javadimon, zubanov@gmail.com
 * Omsk, Russia, created 29.05.2010
 * (C) Copyright by Zubanov Dmitry
 */

package org.jssdb.core.handler;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jssdb.core.Deserializabler;
import org.jssdb.core.utils.SizeException;

/**
 *
 * @author Zubanov Dmitry aka javadimon, zubanov@gmail.com
 * Omsk, Russia,
 * created 08.05.2010
 */
public class DeserializableHandler implements Deserializabler {

    private static DeserializableHandler self = null;
    private long maxMemorySize = 500000000;
    private ArrayList<Object> listClasses = new ArrayList();
    //private static final Class[] parameters = new Class[]{URL.class};
    static final Logger logger = Logger.getLogger(DeserializableHandler.class.getName());

    public void setMaxMemorySize(long maxMemorySize) {
        this.maxMemorySize = maxMemorySize;
    }

    public static DeserializableHandler getDefault() {
        if (self == null) {
            self = new DeserializableHandler();
        }

        return self;
    }

    public void addClass(Class cls) throws Exception {
        listClasses.add(cls);
    }

    public Object deserialaizable(String fileName) {
        Object object = null;
        try {
            FileInputStream fis = null;
            ObjectInputStream in = null;

            fis = new FileInputStream(fileName);
            BufferedInputStream bis = new BufferedInputStream(fis, 8196);
            in = new ObjectInputStream(bis);
            object = in.readObject();
            fis.close();
            bis.close();
            in.close();
            return object;
        } catch (ClassNotFoundException ex) {
            logger.log(Level.SEVERE, fileName, ex);
        } catch (IOException ex) {
            logger.log(Level.SEVERE, fileName, ex);
        }

        return object;
    }

    public ArrayList<Map<Long, Object>> getCollection(ArrayList<File> fileList) throws SizeException {
        if (fileList == null) {
            return null;
        }

        if (fileList.isEmpty()) {
            return null;
        }

        long memory = 0;
        ArrayList<Map<Long, Object>> list = new ArrayList<Map<Long, Object>>();
        for (File file : fileList) {
            memory += file.length();
            if (memory < maxMemorySize) {
                try {
                    Object obj = deserialaizable(file.getCanonicalPath());
                    Map<Long, Object> map = new LinkedHashMap();
                    map.put(Long.parseLong(file.getName()), obj);
                    list.add(map);
                } catch (Exception e) {
                    logger.log(Level.SEVERE, null, e);
                }

            } else {
                throw new SizeException("MaxMemorySize = " + maxMemorySize + ", "
                        + "request memory = " + memory);
            }
        }

        return list;
    }
}
